﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using BrainTechLLC;
using BrainTechLLC.ThreadSafeObjects;
using BrainTechLLC.WPF;
using DragDropLibrary;
using ImageAppDataModels;
using ImageAppViewModels;
using BrainTechLLC.ImageOperatorsNonAForgeDependent;
using BrainTechLLC.ImageOperators;
using BrainTechLLC.FolderExplorer;
using TemporalFilterExtensions;
using System.Drawing;
using System.Windows.Media;
using BrainTechLLC.FilterExtensions;
using System.Windows.Data;
using System.Collections.ObjectModel;
using System.Reflection;
using System.ComponentModel;

namespace WpfImageDuplicates
{
    public partial class ImageCollectionView : UserControl
    {
        protected bool _WantCleanupOldThumbs;

        private void thumbnailView_ThumbVisibilityChanged(object sender, EventArgs e)
        {
            ThumbnailView thumb = sender as ThumbnailView;
            CheckThumbnailViewWiring(thumb);
            _WantCleanupOldThumbs = true;
        }

        private void CleanupOldThumbnails()
        {
            try
            {
                if (this.ThumbsHandler != null && this.ThumbsHandler._thumbsByFileName != null && this.ThumbsHandler._thumbsByFileName.Count > Settings.Values.MaxThumbnailControlsInMemory)
                {
                    var all = this.ThumbsHandler.GetAllThumbnailViews();
                    var allVisible = all.Where(o => o.ThumbVisible == true);
                    var allThumbnailsControl = this.ThumbsHandler._thumbsByFileName.AllItems.Where(tv => !tv.ThumbVisible && !tv.IsSelected && !tv.FileImageViewModel.SelectedByUser).ToList();
                    allThumbnailsControl.Sort(new Comparison<ThumbnailView>((o1, o2) => o1._LastVisible.CompareTo(o2._LastVisible)));
                    int max = Math.Min(allThumbnailsControl.Count, 40);

                    for (int n = max - 1; n >= 0; n--)
                    {
                        var thumbControlToNuke = allThumbnailsControl[n];
                        this.ThumbsHandler._thumbsByFileName.Remove(thumbControlToNuke.FileImageViewModel.FileName);
                        UnwireThumb(thumbControlToNuke);
                        Grid parentGrid = BrainTechLLC.WPF.TempExten.FindParent<Grid>(thumbControlToNuke);
                        thumbControlToNuke.FileImageViewModel = null;
                        thumbControlToNuke.ParentCollectionView = null;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());

            }
        }

        public void UnwireThumb(ThumbnailView thumb)
        {
            thumb.RequestDelete -= thumbnailView_RequestDelete;
            thumb.RequestResizeDelete -= thumbnailView_RequestResizeDelete;
            thumb.RequestRotate -= thumbnailView_RequestRotate;
            thumb.RequestResize -= thumbnailView_RequestResize;
            thumb.WantView -= thumbnailView_WantView;
            thumb.WantSetComparison -= thumbnailView_WantSetComparison;
            thumb.ItemSelectedByUser -= thumbnailView_ItemMarked;
            thumb.ItemDeselectedByUser -= thumb_ItemDeselectedByUser;
            thumb.MouseLeftButtonUp += thumbnailView_MouseLeftButtonDown;
        }

        public void WireThumb(ThumbnailView thumb)
        {
            thumb.RequestDelete += new EventHandler<ObjectEventArgsNonRef<FileImageViewModel, bool>>(thumbnailView_RequestDelete);
            thumb.RequestResizeDelete += new EventHandler<ObjectEventArgsNonRef<FileImageViewModel, bool>>(thumbnailView_RequestResizeDelete);
            thumb.RequestRotate += new EventHandler<ObjectEventArgsNonRef<RotationParams, bool>>(thumbnailView_RequestRotate);
            thumb.RequestResize += new EventHandler<ObjectEventArgsNonRef<FileImageViewModel, bool>>(thumbnailView_RequestResize);
            thumb.WantView += new EventHandler<ObjectEventArgs<FileImageViewModel>>(thumbnailView_WantView);
            thumb.WantSetComparison += new EventHandler<ObjectEventArgsNonRef<FileImageViewModel, bool>>(thumbnailView_WantSetComparison);
            thumb.ItemSelectedByUser += new EventHandler<ObjectEventArgsNonRef<bool>>(thumbnailView_ItemMarked);
            thumb.ItemDeselectedByUser += new EventHandler<ObjectEventArgsNonRef<bool>>(thumb_ItemDeselectedByUser);
            thumb.MouseLeftButtonUp += new MouseButtonEventHandler(thumbnailView_MouseLeftButtonDown);
        }

        void thumb_ItemDeselectedByUser(object sender, ObjectEventArgsNonRef<bool> e)
        {
            var sel = lstItems.GetSelected<FileImageViewModel>();
            var groups = Window1.MainWindow.AllGroups.GetSelectedGroups();

            sel.Where(vm => vm.DeselectedByUser != e.obj).ForEach(vm =>
            {
                vm.DeselectedByUser = e.obj;
                if (e.obj)
                {
                    groups.ForEach(group => Window1.MainWindow.AllGroups.RemoveFileImageFromGroup(vm.FileName, group.GroupName));
                }
            });

            Window1.MainWindow.AllGroups.OnCurrentlySelectedGroupsInListboxChanged();
        }

        private void thumbnailView_ItemMarked(object sender, ObjectEventArgsNonRef<bool> e)
        {
            var sel = lstItems.GetSelected<FileImageViewModel>();
            var groups = Window1.MainWindow.AllGroups.GetSelectedGroups();

            sel.Where(vm => vm.SelectedByUser != e.obj).ForEach(vm =>
            {
                vm.SelectedByUser = e.obj;
                if (e.obj)
                {
                    groups.ForEach(group => Window1.MainWindow.AllGroups.AddFileImageToGroup(vm.FileName, group.GroupName));
                }
            });

            Window1.MainWindow.AllGroups.OnCurrentlySelectedGroupsInListboxChanged();
        }

        private void CheckThumbnailViewWiring(ThumbnailView thumb)
        {
            try
            {
                if (thumb.ThumbVisible && !thumb._isWired)
                {
                    thumb._isWired = true;
                    WireThumb(thumb);
                }
                else if (!thumb.ThumbVisible && thumb._isWired)
                {
                    thumb._isWired = false;
                    UnwireThumb(thumb);
                }

                if (_lastSelected == null && (Displayed.Count > 1 || Displayed.Count == FileImageCollectionViewModel.Count) && FileImageCollectionViewModel.Count > 0)
                {
                    Dispatcher.BeginInvoke(new VoidDelegate(() =>
                    {
                        if (_lastSelected == null)
                        {
                            _lastSelected = FileImageCollectionViewModel[0];
                            var thumbToFocus = FindThumbView(FileImageCollectionViewModel[0].FileImage);
                            if (thumbToFocus != null)
                            {
                                BrainTechLLC.WPF.TempExten.FindParent<ListBoxItem>(thumbToFocus).Focus();
                                ToggleSelection(thumbToFocus.FileImageViewModel, true);
                                this.ClearSelected();
                                this.ToggleSelection(thumbToFocus.FileImageViewModel, true);
                            }
                        }
                    }), System.Windows.Threading.DispatcherPriority.Normal);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private void thumbnailView_SetThumbImage(object sender, EventArgs e)
        {
            ThumbnailView thumb = sender as ThumbnailView;
            if (thumb != null)
            {
                ThumbsHandler.NonDirtyThumbs.Add(thumb, thumb);
            }
        }

        public void MarkThumbImagesDirty()
        {
            ThumbsHandler.MarkThumbImagesDirty();
        }

        public void MarkThumbsDirty()
        {
            if (ThumbsHandler == null)
            {
                // HEREHERE
            }
            else
            {
                ThumbsHandler.MarkThumbsDirty();
            }
        }

        public ThumbnailView FindThumbView(IFileImage image)
        {
            return ThumbsHandler.FindThumbView(image);
        }

        public ThumbnailView FindThumbView(string fileName)
        {
            return ThumbsHandler.FindThumbView(fileName);
        }

        public ThumbnailView FindThumbView(FileImageViewModel vm)
        {
            return ThumbsHandler.FindThumbView(vm.FileImage);
        }

        public void MarkThumbnailFileNameLocationChanged()
        {
            ThumbsHandler.MarkThumbnailFileNameLocationChanged();
        }

        public void MarkThumbnailNeedsClean()
        {
            if (ThumbsHandler != null && ThumbsHandler.ThumbCleanup != null)
            {
                ThumbsHandler.ThumbCleanup.MarkNeedsClean();
            }
        }

        public bool IsSelected(ThumbnailView thumb)
        {
            if (thumb == null)
            {
                return false;
            }
            return thumb.IsSelected;
        }

        public List<ThumbnailView> GetAllThumbnailViews()
        {
            return ThumbsHandler.GetAllThumbnailViews();
        }

        private void thumbnailView_WantSetComparison(object sender, ObjectEventArgsNonRef<FileImageViewModel, bool> e)
        {
            ThumbnailView v = sender as ThumbnailView;

            DoForSelected((item) => item.WantCompare = e.obj2);
            ComparisonHandler.DoCompare(v.FileImageViewModel, e.obj2);
        }

        private void thumbnailView_RequestDelete(object sender, ObjectEventArgsNonRef<FileImageViewModel, bool> e)
        {
            RequestDelete.RaiseEvent(this, e.obj1, e.obj2);
        }

        private void thumbnailView_RequestResizeDelete(object sender, ObjectEventArgsNonRef<FileImageViewModel, bool> e)
        {
            RequestResizeDelete.RaiseEvent(this, e.obj1, e.obj2);
        }

        private void thumbnailView_RequestRotate(object sender, ObjectEventArgsNonRef<RotationParams, bool> e)
        {
            RequestRotate.RaiseEvent(this, e.obj1, e.obj2);
        }

        private void thumbnailView_RequestResize(object sender, ObjectEventArgsNonRef<FileImageViewModel, bool> e)
        {
            RequestResize.RaiseEvent(this, e.obj1, e.obj2);
        }

    }
}